package sk.tramtatiri.pages.users;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.validator.AbstractValidator;
import org.apache.wicket.validation.validator.EmailAddressValidator;
import org.apache.wicket.validation.validator.RangeValidator;
import org.apache.wicket.validation.validator.StringValidator;

import sk.tramtatiri.CaptchaImage;
import sk.tramtatiri.CaptchaInput;
import sk.tramtatiri.EmailAddrExistValidator;
import sk.tramtatiri.PasswordPolicyValidator;
import sk.tramtatiri.WicketApplication;
import sk.tramtatiri.core.CustomizedBeautyTip;
import sk.tramtatiri.data.dao.interfaces.UserDao;
import sk.tramtatiri.data.dao.interfaces.UserInfoDao;
import sk.tramtatiri.data.dataobjects.User;
import sk.tramtatiri.data.dataobjects.UserInfo;

import com.octo.captcha.service.image.ImageCaptchaService;
import com.visural.wicket.behavior.beautytips.BeautyTipBehavior;
import com.visural.wicket.behavior.dateinput.DateInputBehavior;
import com.visural.wicket.behavior.dateinput.DateInputFormat;

public class RegistrationPage extends UserPageTemplate {

	@SpringBean
	private ImageCaptchaService captchaService;
	
	@SpringBean
	private UserDao userDao;
	
	@SpringBean
	private UserInfoDao userInfoDao;

	private FeedbackPanel feedback;
	private TextField<?> name;
	private FormComponent<String> password1;
	private FormComponent<String> password2;
	private TextField<String> emailField;
	private TextField birthDateField;
	private final Date date = new Date(System.currentTimeMillis());
	private DropDownChoice sexChoice;
	private Model model;
	private Date birthDate;
	private TextField<Integer> heightField;
	private TextField<Integer> weightField;
	private TextField<Integer> waistField;

	public RegistrationPage() {
		feedback = new FeedbackPanel("feedback");
		feedback.setOutputMarkupId(true);

		emailField = new TextField<String>("email", Model.of(""));
		emailField.setRequired(true);
		emailField.add(EmailAddressValidator.getInstance());
		emailField.add(new EmailAddrExistValidator(userDao));
		emailField.setLabel(new ResourceModel("label_email"));
		
		password1 = new PasswordTextField("password1", Model.of(""));
		password1.add(StringValidator.minimumLength(8));
		password1.add(new PasswordPolicyValidator());
		password1.setRequired(true);
		password1.setLabel(new ResourceModel("label_password"));
		
		password2 = new PasswordTextField("password2", Model.of(""));
		password2.setRequired(true);
		password2.setLabel(new ResourceModel("label_password2"));
		
		name = new TextField<String>("nickname", Model.of(""));
		name.setRequired(true);
		name.setLabel(new ResourceModel("label_nickname"));
		
		model = new Model("");
		List sexes = new ArrayList();
		sexes.add("Zena");
		sexes.add("Muz");
		sexChoice = new DropDownChoice("sex", model, sexes);
		sexChoice.setRequired(true);
		sexChoice.setLabel(new ResourceModel("label_sex"));

		Model dateModel = new Model();
		birthDateField = new TextField("birthDate", dateModel);
		birthDateField.add(new DateInputBehavior().setDateFormat(DateInputFormat.DD_MM_YYYY));
		birthDateField.setRequired(true);
		birthDateField.setLabel(new ResourceModel("label_dateOfBirth"));
		
		heightField = new TextField<Integer>("height", new Model(""), Integer.class);
		heightField.add(new RangeValidator<Integer>(50,250));
		heightField.setRequired(true);
		heightField.setLabel(new ResourceModel("label_height"));
		
		weightField = new TextField<Integer>("weight", new Model(""), Integer.class);
		weightField.add(new RangeValidator<Integer>(25,350));
		weightField.setRequired(true);
		weightField.setLabel(new ResourceModel("label_weight"));
		
		waistField = new TextField<Integer>("waist", new Model(""), Integer.class);
		waistField.add(new RangeValidator<Integer>(25,300));
		waistField.setRequired(true);
		waistField.setLabel(new ResourceModel("label_waist"));
		
		String challengeId = UUID.randomUUID().toString();
	    final CaptchaImage captchaImage = new CaptchaImage("captchaImage", challengeId) {
	      @Override
	      protected ImageCaptchaService getImageCaptchaService() {
	        return captchaService;
	      }
	    };
	    captchaImage.setOutputMarkupId(true);    
	    
	    
	    final CaptchaInput captchaInput = new CaptchaInput("captchaInput", new Model<String>(), challengeId) {
	      @Override
	      protected ImageCaptchaService getImageCaptchaService() {
	        return captchaService;
	      }
	      
		@Override
		protected void onError(AbstractValidator<String> validator,
				IValidatable<String> validatable) {
			validator.error(validatable, "error.captcha.failed");
			
		}
	    };
	    captchaInput.setOutputMarkupId(true);
	    
	    
	    AjaxLink<Void> refreshCaptcha = new AjaxLink<Void>("captchaRefresh") {
	      @Override
	      public void onClick(AjaxRequestTarget target) {
	        target.addComponent(captchaImage);
	        target.addComponent(captchaInput);
	      }
	    };
	    
	    
		Form<?> form = new Form<Void>("registrationForm") {

			@Override
			protected void onSubmit() {
				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
				if (!birthDateField.getInput().equals("")) {
					try {
						birthDate = sdf.parse(birthDateField.getInput());
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
				String sexPom = (String) model.getObject();
				User newUser = new User();
				newUser.setBirthDate(birthDate);
				newUser.setEmail(emailField.getInput());
				newUser.setHeight(Integer.parseInt(heightField.getInput()));
				newUser.setNickName(name.getInput());
				newUser.setPassword(((WicketApplication)getApplication()).hashPassword(password1.getInput()));
				newUser.setSex(sexPom);
				userDao.save(newUser);
				
				Calendar cal = Calendar.getInstance();
				cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
				
				User createdUser = userDao.findUserByEmail(emailField.getInput());
				UserInfo uinfo = new UserInfo();
				uinfo.setDate(new Date(cal.getTimeInMillis()));
				uinfo.setUser_id(createdUser.getId());
				uinfo.setWaist(Integer.parseInt(waistField.getInput()));
				uinfo.setWeight(Integer.parseInt(weightField.getInput()));
				uinfo.setUser(createdUser);
				
				userInfoDao.save(uinfo);
				
				UserInfo createdUinfo = userInfoDao.load(createdUser.getId());
				createdUser.getUserInfos().add(createdUinfo);
				
				getSession().info(getString("message_registration_successful"));
				setResponsePage(LoginPage.class);
			}
		};

		form.add(new Button("btnToHome") {
			@Override
			public void onSubmit() {
				getRequestCycle().setRedirect(true);
				setResponsePage(UserHomePage.class);
			}
		}.setDefaultFormProcessing(false));

		form.add(new EqualPasswordInputValidator(password1, password2));
		add(form);

		form.add(emailField.add(new CustomizedBeautyTip("Zadaj e-mailovu adresu").getTip()));
		form.add(password1.add(new CustomizedBeautyTip("Zadaj heslo").getTip()));
		form.add(password2.add(new CustomizedBeautyTip("Opakuj heslo").getTip()));
		form.add(name.add(new CustomizedBeautyTip("Zadaj meno").getTip()));
		form.add(birthDateField.add(new CustomizedBeautyTip("Zvol svoj datum narodenia").getTip()));
		form.add(sexChoice.add(new CustomizedBeautyTip("Zvol svoje pohlave").getTip()));
		form.add(heightField.add(new CustomizedBeautyTip("Zadaj vysku").getTip()));
		form.add(weightField.add(new CustomizedBeautyTip("Zadaj vahu").getTip()));
		form.add(waistField.add(new CustomizedBeautyTip("Zadaj obvod pasa").getTip()));
		form.add(captchaImage);
		form.add(captchaInput.add(new CustomizedBeautyTip("Opis kod z obrazka").getTip()));
		form.add(refreshCaptcha);
		add(feedback);
	}

	@Override
	public String getPageTitle() {
		return "chudnite-zdravo.com - Registracia";
	}
	
}
